package com.atguigu.tingshu.account.service.impl;

import com.atguigu.tingshu.account.mapper.UserAccountDetailMapper;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.model.account.UserAccountDetail;
import com.atguigu.tingshu.vo.account.AccountDeductVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private UserAccountDetailMapper userAccountDetailMapper;

    @Override
    public void initUserAccount(Long userId) {
        //	user_account
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userId);
        userAccount.setTotalAmount(new BigDecimal("1000"));
        userAccount.setAvailableAmount(new BigDecimal("1000"));
        userAccountMapper.insert(userAccount);
    }

    @Override
    public BigDecimal getAvailableAmount(Long userId) {
        //	sql: select available_amount from user_account where user_id = ? and is_deleted = 0;
        // SELECT id,user_id,total_amount,lock_amount,available_amount,total_income_amount,total_pay_amount,create_time,update_time,is_deleted FROM user_account WHERE is_deleted=0 AND (user_id = ?)
        LambdaQueryWrapper<UserAccount> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserAccount::getUserId, userId).select(UserAccount::getAvailableAmount);
        UserAccount userAccount = userAccountMapper.selectOne(wrapper);
        //	返回数据
        return userAccount.getAvailableAmount();
    }

    @Override
    @Transactional
    public int checkAndDeduct(AccountDeductVo accountDeductVo) {
        //	1. 检查余额是否足够
        BigDecimal availableAmount = getAvailableAmount(accountDeductVo.getUserId());
        if (availableAmount.compareTo(accountDeductVo.getAmount()) < 0) {
            log.error("余额不足");
        }
        //	2. 扣减余额
        //	UPDATE user_account SET total_amount = total_amount - ?,
        //	available_amount = available_amount - ?, total_pay_amount = total_pay_amount + ?,
        //	update_time = ? WHERE is_deleted = 0 AND (user_id = ?)
        int rows = userAccountMapper.checkAndDeduct(accountDeductVo.getUserId(), accountDeductVo.getAmount());
        //  判断是否扣减成功，并更新用户账户明细
        if (rows == 1) {
            //	更新用户账户明细
            //  记录当前账户资金流向;
            this.addUserAccountDetail(
                    accountDeductVo.getUserId(),
                    accountDeductVo.getContent(),
                    SystemConstant.ACCOUNT_TRADE_TYPE_MINUS,
                    accountDeductVo.getAmount(),
                    accountDeductVo.getOrderNo()
            );
        }
        //	3. 返回扣减结果
        return rows;
    }

    /**
     * 更新用户账户明细
     * @param userId
     * @param content
     * @param accountTradeTypeMinus
     * @param amount
     * @param orderNo
     */
    private void addUserAccountDetail(Long userId, String content, String accountTradeTypeMinus, BigDecimal amount, String orderNo) {
        //	更新用户账户明细
        //  创建对象
        UserAccountDetail userAccountDetail = new UserAccountDetail();
        userAccountDetail.setUserId(userId);
        userAccountDetail.setTitle(content);
        userAccountDetail.setTradeType(accountTradeTypeMinus);
        userAccountDetail.setAmount(amount);
        userAccountDetail.setOrderNo(orderNo);
        userAccountDetailMapper.insert(userAccountDetail);
    }
}
